//
// Created by ta&to on 2022/8/16.
//
#include "lstring.h"
void strcpyfromlen(char *desc, char *src, size_t srcfrom, size_t descto, size_t len) {
    for (int i = 0;i < len;i++) {
        desc[descto] = src[srcfrom];
        descto++;
        srcfrom++;
    }
}
char **strancat(char **desc, char *src, int size) {
    int canuse = mallen(*desc);
    int hasuse = strlen(*desc);
    while(canuse < (size + hasuse)){
       *desc = http_realloc(*desc, size + hasuse);
       canuse = mallen(*desc);
    }
    strncat((char*)*desc, src, size);
    return desc;
}
char * stracat(char* desc, char* src, int size)
{      
	char * desc_temp = NULL;
    desc_temp = (char *)realloc(desc, (strlen(desc)+strlen(src)) * sizeof(char));
	if(desc_temp == NULL)
	{
		return desc;
	}
	if(desc_temp != desc)
	{
		http_free(desc);
		desc = NULL;
	}
    char* ret = desc_temp;  
    while (*desc_temp != '\0') 
            desc_temp++;
    
    while ( size-- )
    {
            if ('\0' != *src)
            {
                memcpy(desc_temp++, src++, 1);
            } else {
				desc_temp = ret;
                return ret;
            }
    }
    *desc_temp = '\0';
	return ret;
}


char *substring(char* desc, char *src, int len, int start)
{
        char * p = desc;
        char * q = src;
        int length = strlen(src);
        if(start>=length || start<0)
                return NULL;
        if(len>length)
                len = length - start;
        q += start;
        while(len--)
                *(p++) = *(q++);
        *(p++) = '\0';
        return desc;
}

int lastindexof(char *src, char *target)
{
    int len_str = strlen(src);
    int len_substr = strlen(target);
    int last_index = -1;

    if (len_substr == 0 || len_str == 0) {
        return -1; // 如果任一字符串为空，则返回-1
    }

    for (int i = 0; i <= len_str - len_substr; i++) {
        if (strncmp(&src[i], target, len_substr) == 0) { // 使用 strncmp 函数比较子串
            last_index = i; // 更新最后找到的位置
        }
    }

    return last_index;
}

int indexof(char *src, char *target)
{
        int num = 1,index = 0;
        char * p = src;
        char * t = target;
        while(*p != '\0')
        {
                if(*(p++) != *(t++))
                {
                        t = target;
                        index += num;
                        num = 1;
                }else{
                        num++;
                }
                if(*t == '\0')
                        return index;
        }
        if(*t == '\0')
                return index;
        return -1;
}
int indexnof(char *src, int srclen, char *target, int targetlen)
{
    int num = 1,index = 0;
    char * p = src;
    char * t = target;
    int pl = srclen;
    int tl = targetlen;
    while(pl--)
    {
        if(*(p++) != *(t++))
        {
            t = target;
            index += num;
            num = 1;
            tl = targetlen;
        }else{
            num++;
            tl--;
        }
        if(!tl)
            return index;
    }
    if(!tl)
        return index;
    return -1;
}
int isEmpty(char *str)
{
    if (str == NULL)
        return 1;
    if (*str == '\0')
        return 1;
    return 0;
}
char* trim(char *src)
{
	char * out = (char *)http_malloc(strlen(src) * sizeof(char));
        int i, j;
        i = 0;
        j = strlen(src);
        while(src[i] == ' ')
                ++i;
        while(src[j] == ' ')
                --j;

        substring(out, src, j-i, i);
	return out;
}

/* 返回10进制 数字的位数 */
uint32_t digits10(int64_t v) {
    if (v < 10) return 1;
    if (v < 100) return 2;
    if (v < 1000) return 3;
    if (v < 1000000000000UL) {
        if (v < 100000000UL) {
            if (v < 1000000) {
                if (v < 10000) return 4;
                return 5 + (v >= 100000);
            }
            return 7 + (v >= 10000000UL);
        }
        if (v < 10000000000UL) {
            return 9 + (v >= 1000000000UL);
        }
        return 11 + (v >= 100000000000UL);
    }
    return 12 + digits10(v / 1000000000000UL);
}
/*将一个无符号的长整型数字转为字符串*/
int ull2string(char *dst, size_t dstlen, unsigned long long value) {
    static const char digits[10] = "0123456789";

    /* Check length. */
    uint32_t length = digits10(value);
    if (length >= dstlen) return 0;         // 目标长度比真实长度小则出错

    /* Null term. */
    uint32_t next = length - 1;
    dst[next + 1] = '\0';                   // 字符串以'\0'结尾

    while (value >= 10) {                   // 这里一位一位的处理字符串
        int const i = (value % 10);
        value /= 10;
        dst[next] = digits[i];          // 赋值
        next -= 1;
    }

    if(value < 10) {
        dst[next] = digits[value];
    }

    return length;
}

int ll2string(char *dst, size_t dstlen, long long svalue) {
    unsigned long long value;
    int negative = 0;

    /* The ull2string function with 64bit unsigned integers for simplicity, so
     * we convert the number here and remember if it is negative. */
    if (svalue < 0) {
        if (svalue != LLONG_MIN) {
            value = -svalue;
        } else {
            value = ((unsigned long long) LLONG_MAX) + 1;
        }
        if (dstlen < 2)
            return 0;
        negative = 1;
        dst[0] = '-';
        dst++;
        dstlen--;
    } else {
        value = svalue;
    }
    /* Converts the unsigned long long value to string*/
    int length = ull2string(dst, dstlen, value);
    if (length == 0) return 0;
    return length + negative;
}

/* Convert a string into a long long. Returns 1 if the string could be parsed
 * into a (non-overflowing) long long, 0 otherwise. The value will be set to
 * the parsed value when appropriate.
 *
 * Note that this function demands that the string strictly represents
 * a long long: no spaces or other characters before or after the string
 * representing the number are accepted, nor zeroes at the start if not
 * for the string "0" representing the zero number.
 *
 * Because of its strictness, it is safe to use this function to check if
 * you can convert a string into a long long, and obtain back the string
 * from the number without any loss in the string representation. */
int string2ll(const char *s, size_t slen, long long *value) {
    const char *p = s;
    size_t plen = 0;
    int negative = 0;
    unsigned long long v;

    /* A string of zero length or excessive length is not a valid number. */
    if (plen == slen || slen >= LONG_STR_SIZE)
        return 0;

    /* Special case: first and only digit is 0. */
    if (slen == 1 && p[0] == '0') {
        if (value != NULL) *value = 0;
        return 1;
    }

    /* Handle negative numbers: just set a flag and continue like if it
     * was a positive number. Later convert into negative. */
    if (p[0] == '-') {
        negative = 1;
        p++; plen++;

        /* Abort on only a negative sign. */
        if (plen == slen)
            return 0;
    }

    /* First digit should be 1-9, otherwise the string should just be 0. */
    if (p[0] >= '1' && p[0] <= '9') {
        v = p[0]-'0';
        p++; plen++;
    } else {
        return 0;
    }

    /* Parse all the other digits, checking for overflow at every step. */
    while (plen < slen && p[0] >= '0' && p[0] <= '9') {
        if (v > (ULLONG_MAX / 10)) /* Overflow. */
            return 0;
        v *= 10;

        if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */
            return 0;
        v += p[0]-'0';

        p++; plen++;
    }

    /* Return if not all bytes were used. */
    if (plen < slen)
        return 0;

    /* Convert to negative if needed, and do the final overflow check when
     * converting from unsigned long long to long long. */
    if (negative) {
        if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */
            return 0;
        if (value != NULL) *value = -v;
    } else {
        if (v > LLONG_MAX) /* Overflow. */
            return 0;
        if (value != NULL) *value = v;
    }
    return 1;
}



/* Convert a string representing an amount of memory into the number of
 * bytes, so for instance memtoull("1Gb") will return 1073741824 that is
 * (1024*1024*1024).
 *
 * On parsing error, if *err is not NULL, it's set to 1, otherwise it's
 * set to 0. On error the function return value is 0, regardless of the
 * fact 'err' is NULL or not. */
unsigned long long memtoull(const char *p, int *err) {
    const char *u;
    char buf[128];
    long mul; /* unit multiplier */
    unsigned long long val;
    unsigned int digits;

    if (err) *err = 0;

    /* Search the first non digit character. */
    u = p;
    if (*u == '-') {
        if (err) *err = 1;
        return 0;
    }
    while(*u && isdigit(*u)) u++;
    if (*u == '\0' || !strcasecmp(u,"b")) {
        mul = 1;
    } else if (!strcasecmp(u,"k")) {
        mul = 1000;
    } else if (!strcasecmp(u,"kb")) {
        mul = 1024;
    } else if (!strcasecmp(u,"m")) {
        mul = 1000*1000;
    } else if (!strcasecmp(u,"mb")) {
        mul = 1024*1024;
    } else if (!strcasecmp(u,"g")) {
        mul = 1000L*1000*1000;
    } else if (!strcasecmp(u,"gb")) {
        mul = 1024L*1024*1024;
    } else {
        if (err) *err = 1;
        return 0;
    }

    /* Copy the digits into a buffer, we'll use strtoll() to convert
     * the digit (without the unit) into a number. */
    digits = u-p;
    if (digits >= sizeof(buf)) {
        if (err) *err = 1;
        return 0;
    }
    memcpy(buf,p,digits);
    buf[digits] = '\0';

    char *endptr;
    errno = 0;
    val = strtoull(buf,&endptr,10);
    if ((val == 0 && errno == EINVAL) || *endptr != '\0') {
        if (err) *err = 1;
        return 0;
    }
    return val*mul;
}

/* 查询内存中字符串第一次出现的地方
 */
const char *mempbrk(const char *s, size_t len, const char *chars, size_t charslen) {
    for (size_t j = 0; j < len; j++) {
        for (size_t n = 0; n < charslen; n++)
            if (s[j] == chars[n]) return &s[j];
    }

    return NULL;
}


/*替换s字符串中的字符 将from 替换成 to
 */
char *memmapchars(char *s, size_t len, const char *from, const char *to, size_t setlen) {
    for (size_t j = 0; j < len; j++) {
        for (size_t i = 0; i < setlen; i++) {
            if (s[j] == from[i]) {
                s[j] = to[i];
                break;
            }
        }
    }
    return s;
}

/* Convert a string into a long. Returns 1 if the string could be parsed into a
 * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
 * value when appropriate. */
int string2l(const char *s, size_t slen, long *lval) {
    long long llval;

    if (!string2ll(s,slen,&llval))
        return 0;

    if (llval < LONG_MIN || llval > LONG_MAX)
        return 0;

    *lval = (long)llval;
    return 1;
}

int hex2dec(char c) {
    if(c>='0' && c <= '9')
        return c - '0';
    if(c >= 'a' && c <= 'f')
        return c - 'a' + 10;
    if(c >= 'A' && c <= 'F')
        return c - 'A' + 10;
    return 0;
}

int htoi(char *hex) {
    int dec = 0;
    int len = strlen(hex);

    for (int i = 0; i < len; i++) {
        char c = hex[i];
        int digit = hex2dec(c);
        dec = dec * 16 + digit;
    }

    return dec;
}

int regex(char *src, char *pattern, regmatch_t nmatch[], size_t size) {
    regex_t    preg;
    int        rc;

    if ((rc = regcomp(&preg, pattern, REG_EXTENDED)) != 0) {
        regfree(&preg);
        return -1;
    }

    rc = regexec(&preg, src, size, nmatch, 0);

    regfree(&preg);

    if (!rc) { // 如果匹配成功，pmatch[0]将包含匹配的子串的起始和结束位置信息（相对于string）
        return rc;
    }
    return -1;
}
// 比较两个字符串不区分大小写
int memcasecmp(const void *str1, const void *str2, size_t n) {
    const unsigned char *s1 = str1;
    const unsigned char *s2 = str2;

    while (n--) {
        unsigned char c1 = tolower(*s1++);
        unsigned char c2 = tolower(*s2++);
        if (c1 != c2) {
            return c1 - c2;
        }
    }
    return 0;
}